package sjtu.ist.warehouse4ws.epc2bpmn;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;




import sjtu.ist.warehouse4ws.model.Epcunit;
import sjtu.ist.warehouse4ws.model.Epcunits;
import sjtu.ist.warehouse4ws.tool.file.Change2UTF;


public class ParserEpc {
	public static Epcunits parse(String rootPath) throws SAXException, IOException, ParserConfigurationException   {
	    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
	    Epcunits sourceDatas=new Epcunits();
	    try{
		 	DocumentBuilder db = dbf.newDocumentBuilder();
		 	
		 	
		 	Change2UTF.change(rootPath);  //change other coded file to UTF-8
		 	File file = new File(rootPath);
           
            Document doc = db.parse(file); 
            NodeList nodelist= doc.getElementsByTagName("epc");  
            
            NamedNodeMap head=nodelist.item(0).getAttributes();
	        String headName=head.item(1).getNodeValue();
	        
	      
           
            Element node1= (Element) nodelist.item(0);   //show the epc Node
           	//print the node tag name
       
            NodeList epcList=  node1.getChildNodes();     //get the children of epc Node
           
            Epcunit start=new Epcunit();        //the start point of the process
            start.setType("start");
            start.setName(headName);
            start.setId(0);
            sourceDatas.getEpcUnits().add(start);
           
           
            int next=Integer.parseInt(epcList.item(1).getAttributes().item(0).getNodeValue());
           
            sourceDatas.bulidRelationship(0, next);
           
            int max=0;
            for(int i=1;i<epcList.getLength();i=i+2){
    	        Element typeNode =(Element) epcList.item(i);
    	        String type=typeNode.getTagName();          //get the type value of the tag;
    	       
    	        NodeList valueNodes=typeNode.getChildNodes(); 
    	       
    	        Element nameNode=(Element)valueNodes.item(1);
    	       
    	        if (type!="arc" && type!="relation")
    	        {
    	    	    NamedNodeMap attributes=typeNode.getAttributes(); //get the attribute's value in the tag
        	        int nodeId=Integer.parseInt(attributes.item(0).getNodeValue()); //get the id of the node
        	        if (max<nodeId) max=nodeId;
        	        Epcunit nodeData=new Epcunit();          //set the type
        	        if (type !="and" && type !="or" && type !="xor") {
        	    	    nodeData.setType(type);
        	    	    nodeData.setName(nameNode.getFirstChild().getNodeValue()); //set the name
        	        }
        	       else{
        	    	   nodeData.setType("connector"); 
        	    	   nodeData.setName(type);
        	       }
        	       
        	       nodeData.setId(nodeId);
        	       
        	       sourceDatas.getEpcUnits().add(nodeData);
    	           
    	       }
    	       else if (type=="arc"){
    	    	   NamedNodeMap nexts=nameNode.getAttributes();
    	    	  
    	    	   int targetId=Integer.parseInt(nexts.item(1).getNodeValue());
    	    	   int sourceId=Integer.parseInt(nexts.item(0).getNodeValue());
    	    	   
    	    	   sourceDatas.bulidRelationship(sourceId, targetId);
    	    	   
    	    	   
    	       } 
    	       
    	       else {
                   NamedNodeMap nexts=typeNode.getAttributes();
                  
    	    	   int targetId=Integer.parseInt(nexts.item(1).getNodeValue());
    	    	   int sourceId=Integer.parseInt(nexts.item(0).getNodeValue());
    	    	   
    	    	   sourceDatas.findSourceDataById(sourceId).setParticipant(targetId);
    	    	   
    	       }
    	       
    	      
    	       
           }
           Epcunit end=new Epcunit();        //the start point of the process
           end.setType("end");
           end.setName("End");
           end.setId(max+1);
           sourceDatas.getEpcUnits().add(end);
           return sourceDatas;
          
	      }finally{}
    }
}
